package com.beiding.businessplatform.ql;

import com.example.demo.auto.model.A;

import java.util.*;

public class QlUtils {

    public static class Ql {
        private Map<String,Object> params;
        private String ql;

        public String getQl() {
            return ql;
        }

        public Map<String, Object> getParams() {
            return params;
        }
    }


    public static Ql makeQl(SelectionBuilder selectionBuilder, QueryBuilder queryBuilder) {

        Set<QueryField> queryFields = new HashSet<>();

        Set<QueryField> select = selectionBuilder.getSelect();

        queryFields.addAll(select);

        queryFields.addAll(queryBuilder.getQueryFields());

        TR tr = checkGet(queryFields);

        if (select.size() == 0) {
            select = tr.root.collectAllField();
            selectionBuilder.setSelect(select);
        }

        Set<QueryField> fields = selectionBuilder.getSelect();
        for (QueryField field : new HashSet<>(fields)) {

            if (field.isAll()) {
                fields.addAll(field.getQueryTable().getAllFields());
                fields.remove(field);
            } else {
                //将id添加进入
                QueryField idField = field.getQueryTable().getIdField();
                fields.add(idField);
            }

        }

        BuilderHolder builderHolder = new BuilderHolder();

        queryBuilder.build(builderHolder);

        selectionBuilder.build(builderHolder);

        Ql ql = new Ql();
        ql.ql = "select " + builderHolder.getSelect() + " from " + buildFrom(tr) + " where " + builderHolder.getWhere();
        ql.params = builderHolder.getParams();
        return ql;
    }

    public static String buildFrom(TR tr) {
        List<QueryTable> queryTables = new ArrayList<>(tr.nRoot);
        for (QueryTable table : tr.nRoot) {
            QueryTable t = table;
            while (true) {
                t = t.getParent();
                if (t.isRoot()) {
                    break;
                } else {
                    if (!queryTables.contains(t)) {
                        queryTables.add(t);
                    }
                }
            }
        }
        queryTables.sort(Comparator.comparingInt(QueryTable::getLayer));

        //进行left join的声明操作

        StringBuilder builder = new StringBuilder(tr.root.getTableName() + " " + tr.root.getAs());

        for (QueryTable table : queryTables) {
            builder.append(" left join ").append(table.getKey()).append(" ").append(table.getAs());
        }

        return builder.toString();

    }


    private static class TR {
        private QueryTable root;
        private Set<QueryTable> nRoot;
    }

    private static TR checkGet(Set<QueryField> queryFields) {
        TR tr = new TR();
        tr.nRoot = new HashSet<>();
        for (QueryField field : queryFields) {

            QueryTable queryTable = field.getQueryTable();

            if (!queryTable.isRoot()) {
                tr.nRoot.add(queryTable);
            }

            QueryTable table = queryTable.getRoot();

            if (tr.root == null) {
                tr.root = table;
            } else {
                if (tr.root != table) {
                    throw new RuntimeException("必须是同一个根节点");
                }
            }
        }

        if (tr.root == null) {
            throw new RuntimeException("没有根节点");
        }

        return tr;
    }

    public static void main(String[] args) {

        System.out.println(makeQl(Q.select(A.name,A.bs.name), Q.eq(A.name, "丁常磊").eq(A.bs.name,"石满")));

    }

}
